import { useState } from 'react'
import classNames from 'classnames'
import { SidebarProps } from './type'

const classPrefix = 'rt-index-bar'

export const Sidebar: React.FC<SidebarProps> = (props) => {
  const {
    indexItems,
    activeIndex,
    onActive,
  } = props

  const [interacting, setInteracting] = useState(false)

  return (
    <div
      className={classNames(`${classPrefix}-sidebar`, {
        [`${classPrefix}-sidebar-interacting`]: interacting,
      })}
      onMouseDown={() => {
        setInteracting(true)
      }}
      onMouseUp={() => {
        setInteracting(false)
      }}
      onTouchStart={() => {
        setInteracting(true)
      }}
      onTouchEnd={() => {
        setInteracting(false)
      }}
      onTouchMove={(e) => {
        if (!interacting) return
        const { clientX, clientY } = e.touches[0]
        // 返回给定相对于视口的坐标点下最上层的元素. 如果指定的坐标点在文档的可视范围外，或者两个坐标都是负数，那么结果返回 null
        // pointer-events 设置为 none 的元素会被忽略，且将返回在该元素上层的元素(也就是父元素)
        const target = document.elementFromPoint(
          clientX,
          clientY,
        ) as HTMLElement
        if (!target) return
        const { index } = target.dataset
        if (index) {
          onActive(index)
        }
      }}
    >
      {indexItems.map(({ index, brief }) => {
        const active = index === activeIndex
        return (
          <div
            className={`${classPrefix}-sidebar-row`}
            onMouseDown={() => {
              onActive(index)
            }}
            onTouchStart={() => {
              onActive(index)
            }}
            /**
             * 作用：
             * 手指/鼠标 按下后未松开，interacting=true；
             * 移动过程中 不会 再次触发 onMouseDown/onTouchStart；
             * 此时靠 onTouchMove + document.elementFromPoint 只能 粗略 捕捉坐标；
             * 如果用户 滑得很快 或 指针稍微偏移，elementFromPoint 可能返回 null 或父级容器，丢帧 → 索引跳变。
             * onMouseEnter 作为“保险”，在指针进入任意字母行时立即补一次 onActive，保证拖拽链不断档。
             */
            onMouseEnter={() => {
              if (interacting) {
                onActive(index)
              }
            }}
            data-index={index}
            key={index}
          >
            {interacting && active && (
              <div className={`${classPrefix}-sidebar-bubble`}>{brief}</div>
            )}
            <div
              className={classNames(`${classPrefix}-sidebar-item`, {
                [`${classPrefix}-sidebar-item-active`]: active,
              })}
            >
              <div>{brief}</div>
            </div>
          </div>
        )
      })}
    </div>
  )
}
